package org.budo.ip.location.service.api.util;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.budo.support.lang.util.IoUtil;
import org.budo.support.lang.util.StringUtil;
import org.budo.support.spring.io.util.ResourceUtil;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;

/**
 * @author lmw
 * @see http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201703/t20170310_1471429.html
 */
@Slf4j
public class AdministrativeDivisionUtil {
    private static final Resource divisionDataResource = new ClassPathResource("/META-INF/administrative-division-json");

    private static final Map<String, Integer> divisionToCodeMap = (Map<String, Integer>) ((Object) JSON.parseObject(IoUtil.toString(ResourceUtil.getInputStream(divisionDataResource))));

    public static Integer getProvinceCode(String province) {
        if (StringUtil.isEmpty(province)) {
            return null;
        }

        Map<String, Integer> provinceMap = getProvinceMap();
        Integer code = provinceMap.get(province);
        if (null != code) {
            return code;
        }

        if (!province.endsWith("省")) {
            code = provinceMap.get(province + "省");
        }

        if (null != code) {
            return code;
        }

        log.error("#46 provinceCode=" + code + ", province=" + province);
        return null;
    }

    public static Integer getCityCode(Integer provinceCode, String city) {
        if (null == provinceCode) {
            return null;
        }

        if (StringUtil.isEmpty(city)) {
            return null;
        }

        Map<String, Integer> cityMap = getCityMap(provinceCode);
        Integer code = cityMap.get(city);
        if (null != code) {
            return code;
        }

        if (!city.endsWith("市")) {
            code = cityMap.get(city + "市");
        }

        if (null != code) {
            return code;
        }

        log.error("#73 provinceCode=" + code + ", provinceCode=" + provinceCode + ", city=" + city);
        return null;
    }

    // 2. 返回省编码
    private static Map<String, Integer> getProvinceMap() {
        Map<String, Integer> provinceMap = new HashMap<String, Integer>();
        for (Entry<String, Integer> entry : divisionToCodeMap.entrySet()) {
            if (entry.getValue() % 10000 == 0) {
                provinceMap.put(entry.getKey(), entry.getValue());
            }
        }

        return provinceMap;
    }

    // 3. 根据省编码返回市编码
    private static Map<String, Integer> getCityMap(Integer provinceCode) {
        Map<String, Integer> cityMap = new HashMap<String, Integer>();
        for (Entry<String, Integer> entry : divisionToCodeMap.entrySet()) {
            if (entry.getValue().intValue() != provinceCode.intValue() // 不是省本身
                    && entry.getValue() / 10000 == provinceCode / 10000 // 是属于这个省
                    && entry.getValue() % 100 == 0) { // 是市级
                cityMap.put(entry.getKey(), entry.getValue());
            }
        }

        return cityMap;
    }

    // 1. ip 查询 返回 省编码 市编码
}